package service

import (
	"dispatch-system/models"
	"math/rand"
	"sync"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
)

var dl sync.Mutex

// 定义常量
const (
	// 订单超时时间
	OrderTimeout = 10 * time.Minute
	// 订单完成时间
	OrderFinishTimeout = 5 * time.Minute
	// 等待状态
	WaitingStatus = "waiting"
	// 进行状态
	UnderwayStatus = "underway"
	// 已完成状态
	FinishedStatus = "finished"
	// 已取消状态
	CanceledStatus = "canceled"
	// 出租车繁忙状态
	BusyStatus = "busy"
)

// 创建订单
func CreateOrder(user string) models.Order {
	o := orm.NewOrm()
	order := new(models.Order)
	order.User = user
	order.Status = WaitingStatus
	order.CreateTime = time.Now()
	o.Insert(order)
	dispatchOrder(order)
	return *order
}

// 新增出租车
func AddTaxi(driver string) models.Taxi {
	o := orm.NewOrm()
	taxi := new(models.Taxi)
	taxi.Driver = driver
	taxi.Status = WaitingStatus
	o.Insert(taxi)
	return *taxi
}

// 获取司机派单排行榜
func GetRankings() []models.Taxi {
	o := orm.NewOrm()
	qs := o.QueryTable(new(models.Taxi))
	var taxis []models.Taxi
	qs.OrderBy("-order_count").All(&taxis)
	return taxis
}

func dispatchOrder(order *models.Order) {
	dl.Lock()
	defer dl.Unlock()

	var availableTaxis []models.Taxi
	// 从数据库获取waiting状态的出租车
	o := orm.NewOrm()
	qs := o.QueryTable(new(models.Taxi))
	qs.Filter("status", WaitingStatus).All(&availableTaxis)

	// 如果没有可用的出租车，则返回
	if len(availableTaxis) == 0 {
		return
	}
	// 判断订单状态是否是waiting且创建时间未超过10分钟
	if order.Status != WaitingStatus || time.Now().Sub(order.CreateTime) > OrderTimeout {
		return
	}

	selectedTaxi := availableTaxis[rand.Intn(len(availableTaxis))]
	selectedTaxi.Status = "busy"
	selectedTaxi.OrderCount += 1
	// 更新出租车状态
	o.Update(&selectedTaxi)
	// 更新订单状态
	order.Status = UnderwayStatus
	order.TaxiId = selectedTaxi.Id
	order.StartTime = time.Now()
	o.Update(order)
}

// 订单完成
func OrderFinish() {
	logs.Info("=====订单完成任务开始=====")
	defer logs.Info("=====订单完成任务结束=====")
	o := orm.NewOrm()
	qs := o.QueryTable(new(models.Order))
	// 查询所有underway的订单
	orders := make([]*models.Order, 0)
	qs.Filter("status", UnderwayStatus).All(&orders)
	logs.Info("所有进行中订单：")
	for _, order := range orders {
		logs.Info(order)
	}
	if len(orders) == 0 {
		return
	}
	// 判断订单开始时间是否超过5分钟
	for _, order := range orders {
		if time.Now().Sub(order.StartTime) > OrderFinishTimeout {
			// 更新订单状态
			order.Status = FinishedStatus
			order.EndTime = time.Now()
			o.Update(order)

			// 更新出租车状态
			o = orm.NewOrm()
			taxi := new(models.Taxi)
			taxi.Id = order.TaxiId
			taxi.Status = WaitingStatus
			o.Update(taxi, "status")
		}
	}
}

// 订单超时取消
func OrderTimeoutCancel() {
	logs.Info("=====订单超时取消任务开始=====")
	defer logs.Info("=====订单超时取消任务结束=====")
	// 获取所有等待中订单并按照创建时间排序
	o := orm.NewOrm()
	qs := o.QueryTable(new(models.Order))
	orders := make([]*models.Order, 0)
	qs.Filter("status", WaitingStatus).OrderBy("-create_time").All(&orders)
	logs.Info("所有等待中订单：")
	for _, order := range orders {
		logs.Info(order)
	}
	// 判断订单是否超时
	for _, order := range orders {
		if time.Now().Sub(order.CreateTime) > OrderTimeout {
			// 更新订单状态
			order.Status = CanceledStatus
			o.Update(order)
		} else {
			// 执行派单
			go dispatchOrder(order)
		}
	}
}
